home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / MATH / MATHLIB2 / PCOMPLEX.PAS < prev    next >
Pascal/Delphi Source File  |  1995-10-14  |  12KB  |  433 lines

  1. Unit PCOMPLEX;
  2.  
  3. (* Bibliotheque mathematique pour type complexe *)
  4. (* Version a fonctions et pointeurs *)
  5. (* JD GAYRARD mai 95 *)
  6.  
  7. (* This library is based on functions instead of procedures.
  8.    To allow a function to return complex type, the trick is
  9.    is to use a pointer on the result of the function. All
  10.    functions are of Pcomplex type (^complexe).
  11.    In the main program the function computation is accessed
  12.    by      z := function_name(param1, param2)^ *)
  13.  
  14. {$G+}
  15. {$N+}
  16. {$E-}
  17.  
  18. interface
  19.  
  20. uses MATHLIB, HYPERBOL;
  21.  
  22. const author  = 'GAYRARD J-D';
  23.       version = 'ver 0.0 - 05/95';
  24.  
  25. type complexe = record
  26.                 reel : float;
  27.                 imag : float
  28.                 end;
  29.  
  30. pcomplexe = ^complexe;
  31.  
  32. const _i : complexe = (reel : 0.0; imag : 1.0);
  33.       _0 : complexe = (reel : 0.0; imag : 0.0);
  34.  
  35. var result : complexe; { all functions result points on this varaible }
  36.  
  37. (* quatre operations : +, -, * , / *)
  38. function cadd (z1, z2 : complexe) : pcomplexe;      (* addition *)
  39. function csub (z1, z2 : complexe) : pcomplexe;      (* soustraction *)
  40. function cmul (z1, z2 : complexe) : pcomplexe;      (* multiplication *)
  41. function cdiv (znum, zden : complexe) : pcomplexe;  (* division znum / zden *)
  42.  
  43. (* fonctions complexes particulieres *)
  44. function cneg (z : complexe) : pcomplexe;       (* negatif *)
  45. function ccong (z : complexe) : pcomplexe;      (* conjuge *)
  46. function crcp (z : complexe) : pcomplexe;       (* inverse *)
  47. function ciz (z : complexe) : pcomplexe;        (* multiplication par i *)
  48. function c_iz (z : complexe) : pcomplexe;       (* multiplication par -i *)
  49. function czero : pcomplexe;                     (* return zero *)
  50.  
  51. (* fonctions complexes a retour non complexe *)
  52. function cmod (z : complexe) : float;           (* module *)
  53. function cequal (z1, z2 : complexe) : boolean;  (* compare deux complexes *)
  54. function carg (z : complexe) : float;           (* argument : a / z = p.e^ia *)
  55.  
  56. (* fonctions elementaires *)
  57. function cexp (z : complexe) : pcomplexe;       (* exponantielle *)
  58. function cln (z : complexe) : pcomplexe;        (* logarithme naturel *)
  59. function csqrt (z : complexe) : pcomplexe;      (* racine carre *)
  60.  
  61. (* fonctions trigonometrique directe *)
  62. function ccos (z : complexe) : pcomplexe;       (* cosinus *)
  63. function csin (z : complexe) : pcomplexe;       (* sinus *)
  64. function ctg  (z : complexe) : pcomplexe;       (* tangente *)
  65.  
  66. (* fonctions trigonometriques inverses *)
  67. function carc_cos (z : complexe) : pcomplexe;   (* arc cosinus *)
  68. function carc_sin (z : complexe) : pcomplexe;   (* arc sinus *)
  69. function carc_tg  (z : complexe) : pcomplexe;   (* arc tangente *)
  70.  
  71. (* fonctions trigonometrique hyperbolique *)
  72. function cch (z : complexe) : pcomplexe;        (* cosinus hyperbolique *)
  73. function csh (z : complexe) : pcomplexe;        (* sinus hyperbolique *)
  74. function cth (z : complexe) : pcomplexe;        (* tangente hyperbolique *)
  75.  
  76. (* fonctions trigonometrique hyperbolique inverse *)
  77. function carg_ch (z : complexe) : pcomplexe;    (* arc cosinus hyperbolique *)
  78. function carg_sh (z : complexe) : pcomplexe;    (* arc sinus hyperbolique *)
  79. function carg_th (z : complexe) : pcomplexe;    (* arc tangente hyperbolique *)
  80.  
  81.  
  82.  
  83. implementation
  84.  
  85. (* quatre operations de base +, -, * , / *)
  86.  
  87. function cadd (z1, z2 : complexe) : pcomplexe;
  88. (* addition : r := z1 + z2 *)
  89. begin
  90. result.reel := z1.reel + z2.reel;
  91. result.imag := z1.imag + z2.imag;
  92. cadd := @result
  93. end;
  94.  
  95. function csub (z1, z2 : complexe) : pcomplexe;
  96. (* soustraction : r :=  z1 - z2 *)
  97. begin
  98. result.reel := z1.reel - z2.reel;
  99. result.imag := z1.imag - z2.imag;
  100. csub := @result
  101. end;
  102.  
  103. function cmul (z1, z2 : complexe) : pcomplexe;
  104. (* multiplication : r := z1 * z2 *)
  105. begin
  106. result.reel := (z1.reel * z2.reel) - (z1.imag * z2.imag);
  107. result.imag := (z1.reel * z2.imag) + (z1.imag * z2.reel);
  108. cmul := @result
  109. end;
  110.  
  111. function cdiv (znum, zden : complexe) : pcomplexe;
  112. (* division : r := znum / zden *)
  113. var denom : float;
  114. begin
  115. with zden do denom := (reel * reel) + (imag * imag);
  116. if denom = 0.0
  117.    then begin
  118.         writeln('******** function Cdiv ********');
  119.         writeln('******* DIVISION PAR ZERO ******');
  120.         halt
  121.         end
  122.    else begin
  123.         result.reel := ((znum.reel * zden.reel) + (znum.imag * zden.imag)) / denom;
  124.         result.imag := ((znum.imag * zden.reel) - (znum.reel * zden.imag)) / denom
  125.         end;
  126. cdiv := @result
  127. end;
  128.  
  129. (* fonctions complexes particulieres *)
  130.  
  131. function cneg (z : complexe) : pcomplexe;
  132. (* negatif : r = - z *)
  133. begin
  134. result.reel := - z.reel;
  135. result.imag := - z.imag;
  136. cneg := @result
  137. end;
  138.  
  139. function cmod (z : complexe): float;
  140. (* module : r = |z| *)
  141. begin
  142. with z do cmod := sqrt((reel * reel) + (imag * imag))
  143. end;
  144.  
  145. function carg (z : complexe): float;
  146. (* argument : 0 / z = p ei0 *)
  147. begin
  148. carg := arctan2(z.reel, z.imag)
  149. end;
  150.  
  151. function ccong (z : complexe) : pcomplexe;
  152. (* conjuge : z := x + i.y alors r = x - i.y *)
  153. begin
  154. result.reel := z.reel;
  155. result.imag := - z.imag;
  156. ccong := @result
  157. end;
  158.  
  159. function crcp (z : complexe) : pcomplexe;
  160. (* inverse : r := 1 / z *)
  161. var denom : float;
  162. begin
  163. with z do denom := (reel * reel) + (imag * imag);
  164. if denom = 0.0
  165.    then begin
  166.         writeln('******** function Crcp ********');
  167.         writeln('******* DIVISION PAR ZERO ******');
  168.         halt
  169.         end
  170.    else begin
  171.         result.reel := z.reel / denom;
  172.         result.imag := - z.imag / denom
  173.         end;
  174. crcp := @result
  175. end;
  176.  
  177. function ciz (z : complexe) : pcomplexe;
  178. (* multiplication par i *)
  179. (* z = x + i.y , r = i.z = - y + i.x *)
  180. begin
  181. result.reel := - z.imag;
  182. result.imag := z.reel;
  183. ciz := @result
  184. end;
  185.  
  186. function c_iz (z : complexe) : pcomplexe;
  187. (* multiplication par -i *)
  188. (* z = x + i.y , r = i.z = y - i.x *)
  189. begin
  190. result.reel := z.imag;
  191. result.imag := - z.reel;
  192. c_iz := @result
  193. end;
  194.  
  195. function czero : pcomplexe;
  196. (* return a zero complexe *)
  197. begin
  198. result.reel := 0.0;
  199. result.imag := 0.0;
  200. czero := @result
  201. end;
  202.  
  203. function cequal (z1, z2 : complexe) : boolean;
  204. (* retourne TRUE si z1 = z2 *)
  205. begin
  206. cequal := (z1.reel = z2.reel) and (z1.imag = z2.imag)
  207. end;
  208.  
  209. (* fonctions elementaires *)
  210.  
  211. function cexp (z : complexe) : pcomplexe;
  212. (* exponantielle : r := exp(z) *)
  213. (* exp(x + iy) = exp(x).exp(iy) = exp(x).[cos(y) + i sin(y)] *)
  214. var expz : float;
  215. begin
  216. expz := exp(z.reel);
  217. result.reel := expz * cos(z.imag);
  218. result.imag := expz * sin(z.imag);
  219. cexp := @result
  220. end;
  221.  
  222. function cln (z : complexe) : pcomplexe;
  223. (* logarithme naturel : r := ln(z) *)
  224. (* ln( p exp(i0)) = ln(p) + i0 + 2kpi *)
  225. var modz : float;
  226. begin
  227. with z do modz := (reel * reel) + (imag * imag);
  228. if modz = 0.0
  229.    then begin
  230.         writeln('********* function Cln *********');
  231.         writeln('****** LOGARITHME DE ZERO ******');
  232.         halt
  233.         end
  234.    else begin
  235.    result.reel := ln(modz);
  236.    result.imag := arctan2(z.reel, z.imag);
  237.    cln := @result
  238.         end
  239. end;
  240.  
  241. function csqrt (z : complexe) : pcomplexe;
  242. (* racine carre : r := sqrt(z) *)
  243. var root, q : float;
  244. begin
  245. if (z.reel <> 0.0) or (z.imag <> 0.0)
  246.    then begin
  247.         root := sqrt(0.5 * (abs(z.reel) + cmod(z)));
  248.         q := z.imag / (2.0 * root);
  249.         if z.reel >= 0.0
  250.            then with result do
  251.                 begin
  252.                 reel := root;
  253.                 imag := q
  254.                 end
  255.            else if z.imag < 0.0
  256.                    then with result do
  257.                         begin
  258.                         reel := - q;
  259.                         imag := - root
  260.                         end
  261.                    else with result do
  262.                         begin
  263.                         reel :=  q;
  264.                         imag :=  root
  265.                         end
  266.         end
  267.    else result := z;
  268. csqrt := @result
  269. end;
  270.  
  271. (* fonctions trigonometriques directes *)
  272.  
  273. function ccos (z : complexe) : pcomplexe;
  274. (* cosinus complexe *)
  275. (* cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy) *)
  276. (* cos(ix) = ch(x) et sin(ix) = i.sh(x) *)
  277. begin
  278. result.reel := cos(z.reel) * ch(z.imag);
  279. result.imag := - sin(z.reel) * sh(z.imag);
  280. ccos := @result
  281. end;
  282.  
  283. function csin (z : complexe) : pcomplexe;
  284. (* sinus complexe *)
  285. (* sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy) *)
  286. (* cos(ix) = ch(x) et sin(ix) = i.sh(x) *)
  287. begin
  288. result.reel := sin(z.reel) * ch(z.imag);
  289. result.imag := cos(z.reel) * sh(z.imag);
  290. csin := @result
  291. end;
  292.  
  293. function ctg (z : complexe) : pcomplexe;
  294. (* tangente *)
  295. var ccosz, temp : complexe;
  296. begin
  297. ccosz := ccos(z)^;
  298. if (ccosz.reel = 0.0) and (ccosz.imag = 0.0)
  299.    then begin
  300.         writeln('********* function Ctg *********');
  301.         writeln('******* DIVISION PAR ZERO ******');
  302.         halt
  303.         end
  304.    else begin
  305.         temp := csin(z)^;
  306.         result := cdiv(temp, ccosz)^;
  307.         ctg := @result
  308.         end
  309. end;
  310.  
  311. (* fonctions trigonometriques inverses *)
  312.  
  313. function carc_cos (z : complexe) : pcomplexe;
  314. (* arc cosinus complexe *)
  315. (* arccos(z) = -i.argch(z) *)
  316. begin
  317. z := carg_ch(z)^;
  318. result := c_iz(z)^;
  319. carc_cos := @result
  320. end;
  321.  
  322. function carc_sin (z : complexe) : pcomplexe;
  323. (* arc sinus complexe *)
  324. (* arcsin(z) = -i.argsh(i.z) *)
  325. begin
  326. z := ciz(z)^;
  327. z := carg_sh(z)^;
  328. result := c_iz(z)^;
  329. carc_sin := @result
  330. end;
  331.  
  332. function carc_tg (z : complexe) : pcomplexe;
  333. (* arc tangente complexe *)
  334. (* arctg(z) = -i.argth(i.z) *)
  335. begin
  336. z := ciz(z)^;
  337. z := carg_th(z)^;
  338. result := c_iz(z)^;
  339. carc_tg := @result
  340. end;
  341.  
  342. (* fonctions trigonometriques hyperboliques *)
  343.  
  344. function cch (z : complexe) : pcomplexe;
  345. (* cosinus hyperbolique *)
  346. (* ch(x+iy) = ch(x).ch(iy) + sh(x).sh(iy) *)
  347. (* ch(iy) = cos(y) et sh(iy) = i.sin(y) *)
  348. begin
  349. result.reel := ch(z.reel) * cos(z.imag);
  350. result.imag := sh(z.reel) * sin(z.imag);
  351. cch := @result
  352. end;
  353.  
  354. function csh (z : complexe) : pcomplexe;
  355. (* sinus hyperbolique *)
  356. (* sh(x+iy) = sh(x).ch(iy) + ch(x).sh(iy) *)
  357. (* ch(iy) = cos(y) et sh(iy) = i.sin(y) *)
  358. begin
  359. result.reel := sh(z.reel) * cos(z.imag);
  360. result.imag := ch(z.reel) * sin(z.imag);
  361. csh := @result
  362. end;
  363.  
  364. function cth (z : complexe) : pcomplexe;
  365. (* tangente hyperbolique complexe *)
  366. (* th(x) = sh(x) / ch(x) *)
  367. (* ch(x) > 1 qq x *)
  368. var temp : complexe;
  369. begin
  370. temp := cch(z)^;
  371. z := csh(z)^;
  372. result := cdiv(z, temp)^;
  373. cth := @result
  374. end;
  375.  
  376. (* fonctions trigonometriques hyperboliques inverses *)
  377.  
  378. function carg_ch (z : complexe) : pcomplexe;
  379. (*   arg cosinus hyperbolique    *)
  380. (*                          _________  *)
  381. (* argch(z) = -/+ ln(z + i.V 1 - z.z)  *)
  382. var temp : complexe;
  383. begin
  384. with temp do begin
  385.              reel := 1 - z.reel * z.reel + z.imag * z.imag;
  386.              imag := - 2 * z.reel * z.imag
  387.              end;
  388. temp := csqrt(temp)^;
  389. temp := ciz(temp)^;
  390. temp := cadd(temp, z)^;
  391. temp := cln(temp)^;
  392. result := cneg(temp)^;
  393. carg_ch := @result
  394. end;
  395.  
  396. function carg_sh (z : complexe) : pcomplexe;
  397. (*   arc sinus hyperbolique    *)
  398. (*                    ________  *)
  399. (* argsh(z) = ln(z + V 1 + z.z) *)
  400. var temp : complexe;
  401. begin
  402. with temp do begin
  403.              reel := 1 + z.reel * z.reel - z.imag * z.imag;
  404.              imag := 2 * z.reel * z.imag
  405.              end;
  406. temp := csqrt(temp)^;
  407. temp := cadd(temp, z)^;
  408. result := cln(temp)^;
  409. carg_sh := @result
  410. end;
  411.  
  412. function carg_th (z : complexe) : pcomplexe;
  413. (* arc tangente hyperbolique *)
  414. (* argth(z) = 1/2 ln((z + 1) / (1 - z)) *)
  415. var temp : complexe;
  416. begin
  417. with temp do begin
  418.              reel := 1 + z.reel;
  419.              imag := z.imag
  420.              end;
  421. with result do begin
  422.           reel := 1 - reel;
  423.           imag := - imag
  424.           end;
  425. result := cdiv(temp, result)^;
  426. with result do begin
  427.           reel := 0.5 * reel;
  428.           imag := 0.5 * imag
  429.           end;
  430. carg_th := @result
  431. end;
  432.  
  433. end.